#include "StartupDlg.h"
#include "LoginProgressBtn.h"
#include "QrLoginWidget.h"
#include "ServerComboBox.h"
#include "ProxySettingDlg.h"
#include "FadeTips.h"
#include "../ServerInfo.h"
#include "../login/auth_login_impl.h"
#include <core/StyleMgr.h>
#include <core/ImageMgr.h>
#include <core/common_types.h>
#include <qbprotocol/include/rdClientLocal.h>
#include <qbprotocol/include/ssCmnDefine.h>
#include <widgets/SImageButton.h>
#include <widgets/SLineEdit.h>
#include <widgets/SCheckEx.h>
#include <widgets/SPopupWindow.h>
#include <QStylePainter>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QCheckBox>
#include <QAbstractItemView>
#include <QMenu>
#include <QMouseEvent>
#include <QMessageBox>
#include <qbkernel/include/qb_base.h>

using namespace qb;
enum ButtonId
{
	Setting,
	Min,
	Close,
	Scan
};

static const int s_border_width = 1;
StartupDlg::StartupDlg(QWidget* parent /*= nullptr*/)
	: QDialog(parent)
{
	m_authLogin = new qb::CAuthLoginImpl();
	setWindowFlag(Qt::FramelessWindowHint);
	setAttribute(Qt::WA_TranslucentBackground);
	resize(900, 640);
	setContentsMargins(0, 0, 0, 0);

	QHBoxLayout* mainLayout = new QHBoxLayout(this);
	mainLayout->setSpacing(0);
	mainLayout->setContentsMargins(s_border_width, s_border_width, s_border_width, s_border_width);
	//左侧账号信息
	m_leftLayout = new QVBoxLayout();
	m_leftLayout->setSpacing(0);
	m_leftLayout->setContentsMargins(64, 0, 0, 0);//左侧空白
	m_leftLayout->addStretch();
	QLabel* logo = new QLabel(this);
	SImage* logoImg = ImgMgr::instance().image("guiframe_app_logo");
	if (logoImg)
		logo->setPixmap(QPixmap::fromImage(*logoImg));
	m_leftLayout->addWidget(logo);
	m_leftLayout->addSpacing(12);

	m_loginSettingWidget = new QWidget(this);
	m_leftLayout->addWidget(m_loginSettingWidget);

	QVBoxLayout* loginSettingsLayout = new QVBoxLayout();
	loginSettingsLayout->setContentsMargins(0, 0, 0, 0);
	m_loginSettingWidget->setLayout(loginSettingsLayout);

	loginSettingsLayout->setSpacing(0);
	m_editUser = new SLineEdit("", this);
	m_editUser->setSelectAllWhenFocus(true);
	m_editUser->setFixedSize(240, 40);
	m_editUser->setPlaceholderText(tr("请输入用户名/手机号"));
	QFont f = m_editUser->font();
	f.setPixelSize(15);
	m_editUser->setFont(f);

	LoginUserInfo lui = QuoteServerInfo::instance().userInfo();
	if (!lui.strUser.empty())
		m_editUser->setText(QString::fromStdString(lui.strUser));//UTF-8?

	loginSettingsLayout->addWidget(m_editUser);
	loginSettingsLayout->addSpacing(16);

	m_editPwd = new SLineEdit("",this);
	m_editPwd->setFixedSize(240, 40);
	m_editPwd->setPlaceholderText(tr("请输入密码"));
	m_editPwd->setSelectAllWhenFocus(true);
	m_editPwd->setEchoMode(QLineEdit::Password);
	m_editPwd->setFont(f);
	loginSettingsLayout->addWidget(m_editPwd);
	loginSettingsLayout->addSpacing(16);
	if (lui.savePwd && !lui.strPwd.empty())
		m_editPwd->setText(QString::fromStdString(lui.strPwd));

	m_loginBtn = new LoginProgressBtn(this);
	m_loginBtn->setFixedSize(240, 40);
	loginSettingsLayout->addWidget(m_loginBtn);
	loginSettingsLayout->addSpacing(66);
	connect(m_loginBtn, &LoginProgressBtn::clicked, this, &StartupDlg::login);

	m_cbServers = new ServerCombox(this);
	m_cbServers->setFixedSize(240, 24);
	m_cbServers->setFocusPolicy(Qt::NoFocus);
	updateServerList();
	loginSettingsLayout->addWidget(m_cbServers);
	loginSettingsLayout->addSpacing(8);

	m_rememberPwd = new SCheckEx(tr("记住密码"), this);
	m_rememberPwd->setFixedSize(240, 24);
	m_rememberPwd->setFocusPolicy(Qt::NoFocus);
	loginSettingsLayout->addWidget(m_rememberPwd);
	loginSettingsLayout->addSpacing(8);
	if (lui.savePwd)
		m_rememberPwd->setSelectState(Qt::Checked, false);

	m_autoStart = new SCheckEx(tr("开机启动"), this);
	m_autoStart->setFixedSize(240, 24);
	m_autoStart->setFocusPolicy(Qt::NoFocus);
	loginSettingsLayout->addWidget(m_autoStart);
	loginSettingsLayout->addSpacing(8);
	if (lui.autoRun)
		m_autoStart->setSelectState(Qt::Checked, false);

	QString str = tr("忘记密码?");
	str = QString("<a href=\"http://www.baidu.com\"><font color=#%1>%2</font></a>").arg(StyleMgr::instance().color("TitleWord").rgb(),0,16)
			.arg(str);
	QLabel* lbForget = new QLabel(str, this);
	lbForget->setFixedSize(240, 24);
	lbForget->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
	loginSettingsLayout->addWidget(lbForget);
	loginSettingsLayout->addSpacing(4);

	m_scanWidget = new QrLoginWidget(this);
	m_scanWidget->hide();
	m_leftLayout->addWidget(m_scanWidget);

	str = tr("联系我们 400-119-9898");
	str = QString("<font color=#%1>%2</font>").arg(StyleMgr::instance().color("TitleWord").rgb(), 0, 16)
		.arg(str);
	QLabel* lbContract = new QLabel(str,this);
	lbContract->setFixedSize(240, 24);
	lbContract->setAlignment(Qt::AlignRight);
	m_leftLayout->addWidget(lbContract);

	m_leftLayout->addStretch();
	mainLayout->addLayout(m_leftLayout);

	//标题栏
	QHBoxLayout* titleLayout = new QHBoxLayout();
	titleLayout->setAlignment(Qt::AlignTop);
	titleLayout->setSpacing(4);

	titleLayout->addStretch();
	m_loginSettingBtn = new SImageButton(this, "auth_login_setting");
	m_loginSettingBtn->setIndex(Setting);
	titleLayout->addWidget(m_loginSettingBtn);
	connect(m_loginSettingBtn, &SImageButton::clicked, this, [this](int) {
		QMenu* menu = new QMenu();
		menu->setAttribute(Qt::WA_DeleteOnClose);
		menu->addAction("网络设置", this, [=]() {
			ProxySettingDlg w(this); w.resize(474, 410);
			w.exec();
			});
		menu->popup(mapToGlobal(m_loginSettingBtn->geometry().bottomLeft()));
		 });

	SImageButton* ib = new SImageButton(this, "guiframe_app_min");
	ib->setIndex(Min);
	titleLayout->addWidget(ib);
	connect(ib, &SImageButton::clicked, this, [this](int) { setWindowState(Qt::WindowState::WindowMinimized); });

	ib = new SImageButton(this, "guiframe_app_close");
	ib->setIndex(Close);
	titleLayout->addWidget(ib);
	connect(ib, &SImageButton::clicked, this, [this](int) {reject(); });
	
	mainLayout->addLayout(titleLayout);

	setLayout(mainLayout);
	setTabOrder(m_editUser, m_editPwd);
	setTabOrder(m_editPwd, m_editUser);

	m_loginModeBtn = new SImageButton(this, "auth_login_qrcode");
	m_loginModeBtn->setIndex(Scan);
	m_loginModeBtn->setEnabled(false);
	m_loginModeBtn->setToolTip("敬请期待");
	connect(m_loginModeBtn, &SImageButton::clicked, this, &StartupDlg::onBtnClicked);

	qbBase::getMessageKernel()->RegisterMessageKernelObserver(this);
	connect(this, &StartupDlg::notifyProgress, this, &StartupDlg::OnProgress);
}

QWidget* StartupDlg::serverList()
{
	return m_cbServers;
}

void StartupDlg::paintEvent(QPaintEvent* event)
{
	QStylePainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing);
	painter.setBrush(QBrush(StyleMgr::instance().color("ElementBackground")));
	QPen pen(StyleMgr::instance().color("InnerBorder"), s_border_width);
	painter.setPen(pen);
	painter.drawRoundedRect(rect(), StyleMgr::instance().size("RoundCorner"), StyleMgr::instance().size("RoundCorner"));

	SImage* bkImage = ImgMgr::instance().image("auth_login_bk_default", WidgetStatus::kNormal, devicePixelRatioF());
	if (bkImage)
	{
		int imgWidth = bkImage->width();
		QRect imgRect = rect();
		imgRect.adjust(0, s_border_width, -s_border_width, -s_border_width);
		imgRect.setLeft(imgRect.width() - imgWidth);
		painter.drawImage(imgRect, *bkImage);
	}
}

void StartupDlg::resizeEvent(QResizeEvent*)
{
	QSize s = m_loginModeBtn->sizeHint();
	QRect r(0, 0, s.width(), s.height());
	r.moveBottomLeft(rect().bottomLeft() + QPoint(14, -14));
	m_loginModeBtn->setGeometry(r);
}

static QPoint s_oldPos;
void StartupDlg::mousePressEvent(QMouseEvent* event)
{
	if (event->button() == Qt::LeftButton && childAt(event->pos()) == nullptr)
	{
		setCursor(Qt::SizeAllCursor);
		s_oldPos = event->globalPos();
		m_dragging = true;
	}
}

void StartupDlg::mouseReleaseEvent(QMouseEvent* event)
{
	if (event->button() == Qt::LeftButton)
	{
		setCursor(Qt::ArrowCursor);
		m_dragging = false;
	}
}

void StartupDlg::mouseMoveEvent(QMouseEvent* event)
{
	if (m_dragging && event->buttons() & Qt::LeftButton)
	{
		QPoint offset = event->globalPos() - s_oldPos;
		move(frameGeometry().topLeft() + offset);
		s_oldPos = event->globalPos();
	}
}

void StartupDlg::keyPressEvent(QKeyEvent* event)
{
	if (event->key() == Qt::Key_Enter ||
		event->key()==Qt::Key_Return) {
		login();
		return;
	}
	QDialog::keyPressEvent(event);
}

void StartupDlg::OnProgress(int progress, int result)
{
	m_loginBtn->setLoginProgress(progress);
	if (progress == 100)
	{
		qbBase::getMessageKernel()->DeRegisterMessageKernelObserver(this);
		log_info("Login Sucess!");
		accept();
	}
}

STDMETHODIMP_(void) StartupDlg::OnRecvNetStatus(qb::NetStatus status, short retcode)
{
	if (retcode == E_RC_OK)
	{
		switch (status)
		{
		case qb::eNetStatus_ConnectingLogin:
			notifyProgress(12, 0);
			break;
		case qb::eNetStatus_ConnectedLogin:
			notifyProgress(24, 0);
			break;
		case qb::eNetStatus_VerifyLogin:
			notifyProgress(36, 0);
			break;
		case qb::eNetStatus_ConnectingGW:
			notifyProgress(48, 0);
			break;
		case qb::eNetStatus_ConnectedGW:
			notifyProgress(60, 0);
			break;
		case qb::eNetStatus_VerifyGW:
			notifyProgress(72, 0);
			break;
		case qb::eNetStatus_Authority:
			notifyProgress(84, 0);
			break;
		case qb::eNetStatus_Done:
			notifyProgress(100, 0);
			break;
		default:
			break;
		}
	}
	else if (retcode < 0)
	{
		showErrorMsg(tr("连接服务器失败"));
	}
	else 
	{
		if (retcode == E_RC_PASSWD_ERR || retcode == E_RC_USER_ERR)
		{
			showErrorMsg(tr("账号或密码错误，请重新输入"));
		}
		else if (retcode == E_RC_NOLOGIN)
		{
			showErrorMsg(tr("登录失败，错误码：4，请联系客服"));
		}
		else if (retcode == E_RC_ERROR)
		{
			showErrorMsg(tr("登录失败，错误码：5，请联系客服"));
		}
		else if (retcode == E_RC_VERSION_CHECK)
		{
			showErrorMsg(tr("发现新版本，请更新后登录"));
		}
		else if (retcode == E_RC_IP_CHECK)
		{
			showErrorMsg(tr("您的IP地址与注册不符,请联系客服"));
		}
		else if (retcode == E_RC_CONN_ERR)
		{
			showErrorMsg(tr("由于网络或端口问题连接失败"));
		}
		else if (retcode == E_RC_COOKIE_ERR)
		{
			showErrorMsg(tr("登录超时，请重新登录"));
		}
		else if (retcode == E_RC_MAC_CHECK)
		{
			showErrorMsg(tr("您的设备与注册不符，请联系400客服热线"));
		}
		else if (retcode == E_RC_EXPIRED_USER)
		{
			showErrorMsg(tr("账号过期，请联系客服"));
		}
		else if (retcode == E_RC_IP_IN_BLACKLIST)
		{
			showErrorMsg(tr("登录受限"));
		}
		else if (retcode == E_RC_NOSERVERLIST)
		{
			showErrorMsg(tr("读取服务器列表失败，请联系客服"));
		}
		else if (retcode == eFT_PL_FORCE_QUIT)
		{
			showErrorMsg(tr("您的Qeubee账号被踢,需要重新注销登录"));
		}
	}
}

void StartupDlg::onBtnClicked(int index)
{
	if (index == Scan)
	{
		m_loginByPwd = !m_loginByPwd;
		if (m_loginByPwd)
		{
			m_loginModeBtn->setImgId("auth_login_desktop");
			m_scanWidget->hide();
			m_loginSettingWidget->show();
		}
		else
		{
			m_loginModeBtn->setImgId("auth_login_qrcode");
			QSize s = m_loginSettingWidget->size();
			m_loginSettingWidget->hide();
			m_scanWidget->setFixedSize(s);
			m_scanWidget->show();
		}
	}
}

void StartupDlg::updateServerList()
{
	m_cbServers->clear();
	auto& servers = QuoteServerInfo::instance().serverGroups();
	int index = 0;
	for (auto server : servers)
	{
		m_cbServers->addItem(QString::fromStdWString(server.name));
		m_cbServers->setItemData(index, Good, Qt::DecorationRole);
	}
	m_cbServers->setItemData(0, true, Qt::DisplayPropertyRole);
	//TODO: 测速
	QuoteServerInfo::instance().setCurrentServer(servers[0].index, servers[0].servers[0].index);
}

#include <QToolTip>
void StartupDlg::login()
{
	QString userName = m_editUser->text();
	QString userPwd = m_editPwd->text();
	if (userName.isEmpty())
	{
		showErrorMsg(tr("账号不能为空"));
		return;
	}

	if (userPwd.isEmpty())
	{
		showErrorMsg(tr("密码不能为空"));
		return;
	}

	saveCfg();
	m_loginSettingWidget->setEnabled(false);

	if (m_authLogin->isLogined())
	{
		return;
	}

	m_loginBtn->setLoginState(true);
	m_authLogin->login();
}

void StartupDlg::showErrorMsg(const QString& err)
{
	if (!m_errTips)
	{
		m_errTips = new FadeTips(this);
		m_errTips->setMargin(32, 16);
	}
	m_errTips->hide();
	m_errTips->setMessage(err);
	m_errTips->show();
}

void StartupDlg::saveCfg()
{
	LoginUserInfo lui;
	lui.strUser = m_editUser->text().toStdString();
	lui.strPwd = m_editPwd->text().toStdString();
	lui.savePwd = m_rememberPwd->isSelected();
	lui.autoRun = m_autoStart->isSelected();
	QuoteServerInfo::instance().updateUserInfo(lui);
}
